package us.mooresr.geartrack.client.core.presenter;

import java.util.List;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.annotations.NameToken;

import us.mooresr.geartrack.client.events.ItemChangedEvent;
import us.mooresr.geartrack.client.events.ItemCreatedEvent;
import us.mooresr.geartrack.client.events.ItemDeletedEvent;
import us.mooresr.geartrack.client.events.ItemTypeChangedEvent;
import us.mooresr.geartrack.client.events.ItemTypeCreatedEvent;
import us.mooresr.geartrack.client.events.ItemTypeDeletedEvent;
import us.mooresr.geartrack.client.events.LocationChangedEvent;
import us.mooresr.geartrack.client.events.LocationCreatedEvent;
import us.mooresr.geartrack.client.events.LocationDeletedEvent;
import us.mooresr.geartrack.client.place.NameTokens;
import us.mooresr.geartrack.shared.action.GetAllItemTypesAction;
import us.mooresr.geartrack.shared.action.GetAllItemTypesResult;
import us.mooresr.geartrack.shared.action.GetAllLocationsAction;
import us.mooresr.geartrack.shared.action.GetAllLocationsResult;
import us.mooresr.geartrack.shared.action.PutItem;
import us.mooresr.geartrack.shared.action.DeleteItem;
import us.mooresr.geartrack.shared.action.DeleteItemAction;
import us.mooresr.geartrack.shared.action.DeleteItemResult;
import us.mooresr.geartrack.shared.action.GetAllItemsAction;
import us.mooresr.geartrack.shared.action.GetAllItemsResult;
import us.mooresr.geartrack.shared.action.PutItemAction;
import us.mooresr.geartrack.shared.action.PutItemResult;
import us.mooresr.geartrack.shared.model.Item;
import us.mooresr.geartrack.shared.model.ItemType;
import us.mooresr.geartrack.shared.model.Location;

import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import com.google.inject.Inject;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent;

public class ItemPresenter extends
		Presenter<ItemPresenter.MyView, ItemPresenter.MyProxy> 
		implements ItemUiHandlers {
	
	private final DispatchAsync dispatcher;

	public interface MyView extends View, HasUiHandlers<ItemUiHandlers> {
		public void setItemList(List<Item> items);
		public void addItemToList(Item item);
		public void removeItemFromList(Item item);
		public void updateListEntry(Item item);
		public void setLocations(List<Location> locations);
		public void setItemTypes(List<ItemType> itemTypes);
		public void addLocation(Location location);
		public void removeLocation(Location location);
		public void changeLocation(Location location);
		public void addItemType(ItemType itemType);
		public void removeItemType(ItemType itemType);
		public void changeItemType(ItemType itemType);
		
	}

	@ProxyStandard
	@NameToken(NameTokens.items)
	public interface MyProxy extends ProxyPlace<ItemPresenter> {
	}

	@Inject
	public ItemPresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy, DispatchAsync dispatcher) {
		super(eventBus, view, proxy);
		getView().setUiHandlers(this);
		
		this.dispatcher = dispatcher;

	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, MainPresenter.TYPE_SetMainContent, this);
	}

	/**
	 * Called by the view to tell us that the user has requested an item be deleted
	 */
	@Override
	public void deleteItem(Item item) {
		DeleteItemAction action = new DeleteItemAction(item);
		
		dispatcher.execute(action, new AsyncCallback<DeleteItemResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(DeleteItemResult result) {
				// The update was successful.  Fire an event to tell everyone about it.
				ItemDeletedEvent.fire(getEventBus(), result.getItemOut());
				
			}
			
		});
		
	}

	@Override
	public void addItem(Item item) {
		PutItemAction action = new PutItemAction(item);
		
		dispatcher.execute(action, new AsyncCallback<PutItemResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutItemResult result) {
				// The update was successful.  Fire an event to tell everyone about it.
				ItemCreatedEvent.fire(getEventBus(), result.getItemOut());
			}
			
		});
		
	}

	@Override
	public void updateItem(Item item) {
		PutItemAction action = new PutItemAction(item);
		
		dispatcher.execute(action, new AsyncCallback<PutItemResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutItemResult result) {
				// The update was successful.  Fire an event to tell everyone about it.
				ItemChangedEvent.fire(getEventBus(), result.getItemOut());
			}
			
		});	
		
	}
	
	@Override
	public void onBind() {
		super.onBind();
		
		
		
		addRegisteredHandler(ItemCreatedEvent.getType(), new ItemCreatedEvent.ItemCreatedHandler() {
			
			@Override
			public void onItemCreated(ItemCreatedEvent event) {
				getView().addItemToList(event.getNewItem());
				
			}
			
		});
		
		addRegisteredHandler(ItemDeletedEvent.getType(), new ItemDeletedEvent.ItemDeletedHandler() {
			
			@Override
			public void onItemDeleted(ItemDeletedEvent event) {
				getView().removeItemFromList(event.getItem());
				
				
			}
		});
		
		addRegisteredHandler(ItemChangedEvent.getType(), new ItemChangedEvent.ItemChangedHandler() {
			
			@Override
			public void onItemChanged(ItemChangedEvent event) {
				getView().updateListEntry(event.getItem());
				
			}
		});
		
		addRegisteredHandler(LocationCreatedEvent.getType(), new LocationCreatedEvent.LocationCreatedHandler() {
			
			@Override
			public void onLocationCreated(LocationCreatedEvent event) {
				getView().addLocation(event.getLocation());
				
			}
		});
		
		addRegisteredHandler(LocationDeletedEvent.getType(), new LocationDeletedEvent.LocationDeletedHandler() {
			
			@Override
			public void onLocationDeleted(LocationDeletedEvent event) {
				getView().removeLocation(event.getLocation());
				
			}
		});
		
		addRegisteredHandler(LocationChangedEvent.getType(), new LocationChangedEvent.LocationChangedHandler() {
			
			@Override
			public void onLocationChanged(LocationChangedEvent event) {
				getView().changeLocation(event.getLocation());
				
			}
		});
		
		addRegisteredHandler(ItemTypeCreatedEvent.getType(), new ItemTypeCreatedEvent.ItemTypeCreatedHandler() {
			
			@Override
			public void onItemTypeCreated(ItemTypeCreatedEvent event) {
				getView().addItemType(event.getItemType());
				
			}
		});
		
		addRegisteredHandler(ItemTypeDeletedEvent.getType(), new ItemTypeDeletedEvent.ItemTypeDeletedHandler() {
			
			@Override
			public void onItemTypeDeleted(ItemTypeDeletedEvent event) {
				getView().removeItemType(event.getItemType());
				
			}
		});
		
		addRegisteredHandler(ItemTypeChangedEvent.getType(), new ItemTypeChangedEvent.ItemTypeChangedHandler() {
			
			@Override
			public void onItemTypeChanged(ItemTypeChangedEvent event) {
				getView().changeItemType(event.getItemType());
				
			}
		});
	}
	
	@Override
	public void onReveal() {
		super.onReveal();
		
		// Launch a request to get the item list data
		GetAllItemsAction action = new GetAllItemsAction();
		
		dispatcher.execute(action,  new AsyncCallback<GetAllItemsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GetAllItemsResult result) {
				getView().setItemList(result.getItems());
				
			}
			
		});
		
		// Launch a request to fill in the locations
		GetAllLocationsAction action2 = new GetAllLocationsAction();
		
		dispatcher.execute(action2, new AsyncCallback<GetAllLocationsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GetAllLocationsResult result) {
				getView().setLocations(result.getLocations());
				
			}
			
		});
		
		// Launch a request to fill in the item types
		GetAllItemTypesAction action3 = new GetAllItemTypesAction();
		
		dispatcher.execute(action3, new AsyncCallback<GetAllItemTypesResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GetAllItemTypesResult result) {
				getView().setItemTypes(result.getItemTypes());
				
			}
			
		});
		
	}
}
